package com.xing.yunji.aop;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class AopLog {
    //定义切点
    //@Pointcut(value = "execution(* com.xing.yunji.controller.*.*(..))")
    @Pointcut("@annotation(com.xing.yunji.aop.LogAnnotation)")
    public void pt() {
    }

    //使用环绕通知
    @Around("pt()")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long totalTime = System.currentTimeMillis() - startTime;
        recordLog(joinPoint, totalTime,result);
        return result;
    }

    private void recordLog(ProceedingJoinPoint joinPoint, long totalTime, Object result) throws Exception {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        log.info("======================log start======================");
        log.info("module: {}", logAnnotation.module());
        log.info("operation: {}", logAnnotation.operation());

        String className = joinPoint.getTarget().getClass().getName();
        String methodName = methodSignature.getName();
        log.info("request method: {}", className + "." + methodName + "()");
        //使用数组来获取参数
        Object[] args = joinPoint.getArgs();
        Gson gson = new Gson();
        String params = gson.toJson(args[0]);
        log.info("params: {}",params);
//        log.info("result: {}",result);
        log.info("total time: {}",totalTime);
        log.info("======================log end======================");
    }
}